using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Rotempco.Core.ORM.Interfaces;
using System.Reflection;
using Rotempco.Core.Web.Objects.Stores;


namespace Rotempco.Core.Web.CRUD.Logic
{
    public class ManagerInstanceHelper
    {
        public static IDAL<TDomainObject, TPrimaryKey> GetManagerInstance<TDomainObject, TPrimaryKey>()
        {
            IDAL<TDomainObject, TPrimaryKey> managerInstance = GetExtensionManagerInstance<TDomainObject, TPrimaryKey>();

            if (managerInstance == null)
                managerInstance = GetBaseClassManagerInstance<TDomainObject, TPrimaryKey>();

            if (managerInstance == null)
                throw new Exception("No implementation of " + typeof(TDomainObject).Name + " found");

            return managerInstance;
        }

        private static IDAL<TDomainObject, TPrimaryKey> GetBaseClassManagerInstance<TDomainObject, TPrimaryKey>()
        {
            string baseClassAssemblyName = Assembly.GetExecutingAssembly().GetName().Name.Replace("Core", "BaseClass");
            Assembly assembly = GetAssembly(baseClassAssemblyName);

            string entityClassName = typeof(TDomainObject).Name;

            string typeName = baseClassAssemblyName + ".Managers." + entityClassName + "Manager";
            Type type = assembly.GetType(typeName);

            if (type != null)
                return Activator.CreateInstance(type) as IDAL<TDomainObject, TPrimaryKey>;

            typeName = baseClassAssemblyName + ".DAL." + entityClassName + "Data";
            type = assembly.GetType(typeName);

            if (type != null)
                return Activator.CreateInstance(type) as IDAL<TDomainObject, TPrimaryKey>;

            return null;
        }


        private static IDAL<TDomainObject, TPrimaryKey> GetExtensionManagerInstance<TDomainObject, TPrimaryKey>()
        {
            string websiteAssemblyName = null;

            if (WebStore.Instance.WebsiteName != null)
                websiteAssemblyName = WebStore.Instance.WebsiteName;
            else
                websiteAssemblyName = Assembly.GetExecutingAssembly().GetName().Name.Replace("Core", "Website");

            Assembly assembly = GetAssembly(websiteAssemblyName);

            string nameSpace = typeof(TDomainObject).Namespace;

            string typeName = nameSpace.Substring(0, nameSpace.LastIndexOf('.')) + ".Managers." + typeof(TDomainObject).Name + "Manager";
            Type type = assembly.GetType(typeName);

            if (type != null)
                return Activator.CreateInstance(type, true) as IDAL<TDomainObject, TPrimaryKey>;

            return null;
        }


        private static Assembly GetAssembly(string baseClassAssemblyName)
        {
            Assembly[] assemblyList = AppDomain.CurrentDomain.GetAssemblies();
            Assembly assembly = (from a in assemblyList where a.FullName.Contains(baseClassAssemblyName + ",") select a).First();

            if (assembly != null)
                return assembly;

            return (from a in assemblyList where a.FullName.Contains(baseClassAssemblyName) select a).First();
        }

    }
}